package com.cuile.littletools.scan


import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiManager
import android.os.Bundle
import android.provider.ContactsContract
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import com.amap.api.maps2d.CameraUpdateFactory
import com.amap.api.maps2d.model.CameraPosition
import com.amap.api.maps2d.model.LatLng
import com.amap.api.maps2d.model.MarkerOptions
import com.cuile.littletools.R
import com.cuile.littletools.isHttpUrl
import com.google.zxing.client.android.Intents
import it.auron.library.geolocation.GeoCardParser
import it.auron.library.mecard.MeCardParser
import it.auron.library.vcard.VCardParser
import it.auron.library.wifi.WifiCardParser
import kotlinx.android.synthetic.main.fragment_scan_result.*
import kotlinx.android.synthetic.main.view_contact_qr.*
import kotlinx.android.synthetic.main.view_email_qr.*
import kotlinx.android.synthetic.main.view_location_qr.*
import kotlinx.android.synthetic.main.view_msg_qr.*
import kotlinx.android.synthetic.main.view_net_qr.*
import kotlinx.android.synthetic.main.view_phone_qr.*
import kotlinx.android.synthetic.main.view_txt_qr.*
import kotlinx.android.synthetic.main.view_wifi_qr.*


/**
 * A simple [Fragment] subclass.
 *
 */
class ScanResultFragment : Fragment() {

    lateinit var resultTag: String

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {

        return layoutInflater.inflate(R.layout.fragment_scan_result, null)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        var qrContent = arguments?.getString(Intents.Scan.RESULT, "")
        if ("" == qrContent) qrContent = activity?.intent?.getStringExtra(Intents.Scan.RESULT)

        if (qrContent != null && "" != qrContent) {
            when {
                qrContent.startsWith("mailto:", true) -> {
                    val email = qrContent.substring(7)
                    inflateScanViewStub(R.layout.view_email_qr)
                    emailAddr.setText(email)

                    resultTag = "mailto"
                }
                qrContent.startsWith("tel:", true) -> {
                    val phone = qrContent.substring(4)
                    inflateScanViewStub(R.layout.view_phone_qr)
                    phoneNum.setText(phone)

                    resultTag = "tel"
                }
                qrContent.startsWith("MECARD:", true) -> {
                    val meCard = MeCardParser.parse(qrContent)
                    inflateScanViewStub(R.layout.view_contact_qr)
                    contactName.setText("${if(meCard.surname == null) "" else meCard.surname + ","}${meCard.name}")
                    contactNum.setText(meCard.telephones[0])
                    contactQQ.setText(meCard.note)
                    contactCompany.setText(meCard.org)

                    val tilIndex = qrContent.indexOf("TIL:", 0, true)
                    if (tilIndex >= 0) {
                        val midStr = qrContent.substring(tilIndex + 4)
                        val mid2 = midStr.split(";")
                        if (mid2.isNotEmpty()) {
                            contactPost.setText(mid2[0])
                        }
                    }
                    contactAddr.setText(meCard.address)
                    contactEmail.setText(meCard.email)

                    resultTag = "mecard"
                }

                qrContent.trim().startsWith("BEGIN:VCARD", true) -> {
                    val vCard = VCardParser.parse(qrContent)
                    inflateScanViewStub(R.layout.view_contact_qr)
                    contactName.setText(vCard.name)
                    contactNum.setText(vCard.telephones[0])
                    contactQQ.setText(vCard.note)
                    contactCompany.setText(vCard.company)
                    contactAddr.setText(vCard.address)
                    contactEmail.setText(vCard.emails[0])

                    resultTag = "vcard"
                }

                qrContent.startsWith("smsto:", true) -> {
                    val str = qrContent.substring(6)
                    val n_c = str.split(":")
                    var phoneNumber = ""
                    var content = ""
                    if (n_c.isNotEmpty()) {
                        phoneNumber = n_c[0]
                        if (n_c.size > 1) {
                            content = n_c[1]
                        }
                    }
                    inflateScanViewStub(R.layout.view_msg_qr)
                    msgDesNum.setText(phoneNumber)
                    msgContent.setText(content)

                    resultTag = "smsto"
                }
                qrContent.startsWith("WIFI:", true) -> {
                    val wifiCard = WifiCardParser.parse(qrContent)
                    inflateScanViewStub(R.layout.view_wifi_qr)
                    wifiName.setText(wifiCard.sid)
                    wifiPwd.setText(wifiCard.password)
                    scanResultOpenBtn.text = "连接此WIFI"

                    resultTag = "wifi"
                }
                qrContent.startsWith("URLTO:", true) -> {
                    val url = qrContent.substring(6)
                    if (url.isHttpUrl()) {

                    }
                    inflateScanViewStub(R.layout.view_net_qr)
                    netAddr.setText(url)

                    resultTag = "urlto"
                }
                qrContent.startsWith("geo:", true) -> {
                    val geoCard = GeoCardParser.parse(qrContent)
                    inflateScanViewStub(R.layout.view_location_qr)

                    curMap.onCreate(savedInstanceState)

                    val position = qrContent.substring(4).split(",")
                    val lat = position[0].toDoubleOrNull()
                    val lon = position[1].toDoubleOrNull()
                    if (lon == null || lat == null) {
                        Toast.makeText(context, "坐标解析失败", Toast.LENGTH_LONG).show()
                    } else {
                        curMap.map.moveCamera(CameraUpdateFactory.newCameraPosition(CameraPosition(LatLng(lon, lat),20f, 0f, 0f)))
                        curMap.map.addMarker(MarkerOptions().position(LatLng(lon, lat))).showInfoWindow()
                    }

                    resultTag = "geo"
                }
                else -> {
                    if (qrContent.isHttpUrl()) {
                        inflateScanViewStub(R.layout.view_net_qr)
                        netAddr.setText(qrContent)

                        resultTag = "urlto"
                    } else {
                        inflateScanViewStub(R.layout.view_txt_qr)
                        scanResultOpenBtn.visibility = View.GONE
                        txtContent.setText(qrContent)

                        resultTag = "text"
                    }
                }
            }
        }

        scanResultCopyBtn.setOnClickListener {
            copyToClipBoard()
        }

        scanResultOpenBtn.setOnClickListener {
            openInApps()
        }
    }

    private fun openInApps() {
        when(resultTag) {
            "mailto" -> {
                val uri = Uri.parse("mailto:${emailAddr.text}")
                val intent = Intent(Intent.ACTION_SENDTO, uri)
                if (intent.resolveActivity(context!!.packageManager) != null)
                    startActivity(intent)
            }
            "tel" -> {
                val uri = Uri.parse("tel:${phoneNum.text}")
                val intent = Intent(Intent.ACTION_DIAL, uri)
                if (intent.resolveActivity(context!!.packageManager) != null)
                    startActivity(intent)
            }
            "mecard" -> {
                val intent = Intent(Intent.ACTION_INSERT_OR_EDIT)
                intent.type = ContactsContract.Contacts.CONTENT_ITEM_TYPE
                intent.putExtras(bundleOf(
                        ContactsContract.Intents.Insert.NAME to contactName.text,
                        ContactsContract.Intents.Insert.PHONE to contactNum.text,
                        ContactsContract.Intents.Insert.NOTES to contactQQ.text,
                        ContactsContract.Intents.Insert.EMAIL to contactEmail.text,
                        ContactsContract.Intents.Insert.COMPANY to contactCompany.text,
                        ContactsContract.Intents.Insert.POSTAL to contactPost.text,
                        ContactsContract.Intents.Insert.DATA to contactAddr.text))
                if (intent.resolveActivity(context!!.packageManager) != null)
                    startActivity(intent)
            }
            "vcard" -> {
                val intent = Intent(Intent.ACTION_INSERT_OR_EDIT)
                intent.type = ContactsContract.Contacts.CONTENT_ITEM_TYPE
                intent.putExtras(bundleOf(
                        ContactsContract.Intents.Insert.NAME to contactName.text,
                        ContactsContract.Intents.Insert.PHONE to contactNum.text,
                        ContactsContract.Intents.Insert.NOTES to contactQQ.text,
                        ContactsContract.Intents.Insert.EMAIL to contactEmail.text,
                        ContactsContract.Intents.Insert.COMPANY to contactCompany.text,
                        ContactsContract.Intents.Insert.POSTAL to contactAddr.text,
                        ContactsContract.Intents.Insert.JOB_TITLE to contactPost.text))
                if (intent.resolveActivity(context!!.packageManager) != null)
                    startActivity(intent)
            }
            "smsto" -> {
                val msgBody = msgContent.text.toString()
                val intent = Intent(Intent.ACTION_SENDTO, Uri.fromParts("smsto", msgDesNum.text.toString(), null))
                intent.putExtras(bundleOf(
                        "sms_body" to msgBody
                ))
                if (intent.resolveActivity(context!!.packageManager) != null)
                    startActivity(intent)
            }
            "wifi" -> {
                connectWifi()
            }
            "urlto" -> {
                var url = netAddr.text.toString()
                if ((!url.startsWith("http://", true)) && (!url.startsWith("https://", true))) {
                    url = "http://$url"
                }
                val webpage: Uri = Uri.parse(url)
                val intent = Intent(Intent.ACTION_VIEW, webpage)
                if (intent.resolveActivity(context!!.packageManager) != null)
                    startActivity(intent)

            }
            "geo" -> {
                val intent = Intent(Intent.ACTION_VIEW).apply {
                    val position = curMap.map.mapScreenMarkers[0].position
                    data = Uri.parse("geo:" + position.latitude + "," + position.longitude.toString())
                }
                if (intent.resolveActivity(context!!.packageManager) != null)
                    startActivity(intent)

            }
            "text" -> {

            }
        }
    }

    private fun connectWifi() {
        val ssid = wifiName.text.toString()
        val pwd = wifiPwd.text.toString()
        val type = "WPA/WPA2"

        val wifiManager = context?.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val config = WifiConfiguration()

        config.allowedAuthAlgorithms.clear()
        config.allowedGroupCiphers.clear()
        config.allowedKeyManagement.clear()
        config.allowedPairwiseCiphers.clear()
        config.allowedProtocols.clear()

        config.SSID = "\"" + ssid + "\""
        config.preSharedKey = "\"" + pwd + "\""
        config.allowedAuthAlgorithms
                .set(WifiConfiguration.AuthAlgorithm.OPEN);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
        config.allowedPairwiseCiphers
                .set(WifiConfiguration.PairwiseCipher.TKIP)
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
        config.allowedPairwiseCiphers
                .set(WifiConfiguration.PairwiseCipher.CCMP)
        config.status = WifiConfiguration.Status.ENABLED

        var netId = config.networkId
        if (netId == -1)
            netId = wifiManager.addNetwork(config)
        wifiManager.enableNetwork(netId, true)
    }

    private fun copyToClipBoard() {
        val clipBoardManager = context?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        val qrContent: String
        when(resultTag) {
            "mailto" -> {
                qrContent = emailAddr.text.toString()
            }
            "tel" -> {
                qrContent = phoneNum.text.toString()
            }
            "mecard" -> {
                qrContent = contactName.text.toString() + contactNum.text.toString()
            }
            "vcard" -> {
                qrContent = contactName.text.toString() + contactNum.text.toString()
            }
            "smsto" -> {
                qrContent = msgDesNum.text.toString() + msgContent.text.toString()
            }
            "wifi" -> {
                qrContent = wifiName.text.toString() + wifiPwd.text.toString()
            }
            "urlto" -> {
                qrContent = netAddr.text.toString()
            }
            "geo" -> {
                qrContent = curMap.map.myLocation.toString()
            }
            else -> {
                qrContent = txtContent.text.toString()
            }
        }
        clipBoardManager.primaryClip = ClipData.newPlainText("QrContent", qrContent)
    }

    private fun inflateScanViewStub(id: Int) {
        scanViewStub.layoutResource = id
        scanViewStub.inflate()
    }


    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        curMap?.onSaveInstanceState(outState)
    }

    override fun onResume() {
        super.onResume()
        curMap?.onResume()
    }

    override fun onPause() {
        super.onPause()
        curMap?.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        curMap?.onDestroy()
    }

}
